<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
	<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no,width=device-width,height=device-height">
    <title> Catch Day (React) </title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" rel="stylesheet">
    <link href="catch day.css" rel="stylesheet">
	<script src="babel.min.js"></script>
	<script src="react.development.js"></script>
	<script src="react-dom.development.js"></script>
 </head>

 <body>
 
	<div id="box">
		
    </div>
    <script src='rem.js'>
    </script>
   <script type="text/babel">
        class Contain extends React.Component{
			constructor(){
						super();
						this.state = {
							list:[],
							total:0,
							data : [
								{
									id:0,
									source:'fish.jpg',
									name:'PACIFIC HALIBUT',
									desc:'Everyone favorite white fish.We will cut it to the size you need and ship it.',
									price:1724,
									order:0,
									saling:true
								},
								{
									id:1,
									source:'lobster.jpg',
									name:'LOBSTER',
									desc:'These tender,mouth-watering beauties are a fantastic hit at any dinner party.',
									price:3200,
									order:0,
									saling:false
								},
								{
									id:2,
									source:'scallops.jpg',
									name:'SEA SCALLOPS',
									desc:'Big,sweet and tender.True dry-pack scallops from the icey waters of Alaska.About 8-10 per pound',
									price:1684,
									order:0,
									saling:true
								},
								{
									id:3,
									source:'salmon.jpg',
									name:'ATLANTIC SALMON',
									desc:'This flaky,oily salmon is truly the king of the sea.Bake it,grill it,broil it...as good as it gets!',
									price:1453,
									order:0,
									saling:true
								},
								{
									id:4,
									source:'oyster.jpg',
									name:'OYSTERS',
									desc:'A soft plump oyster with a sweet salty flavor and a clean finish',
									price:2543,
									order:0,
									saling:true
								},
								{
									id:5,
									source:'mussels.jpg',
									name:'MUSSELS',
									desc:'The best mussels from the Pacific Northwest with a full-flavored and complex taste.',
									price:425,
									order:0,
									saling:true
								},
								{
									id:6,
									source:'jumpos.jpg',
									name:'JUMBO PRAWNS',
									desc:'With 21-25 two bite prawns in each pound,these sweet morsels are perfect for shish-kabobs.',
									price:2250,
									order:0,
									saling:true
								}
							]
						}
						this.handleOrder = this.handleOrder.bind(this);
						this.Del = this.Del.bind(this);
						this.Change = this.Change.bind(this);
						this.select = this.select.bind(this);
						this.Add = this.Add.bind(this);
						this.Reduce = this.Reduce.bind(this);
					}
			Del(order,index){
				//删除订单顺序索引对应订单
				var current = this.state.list;
				current.splice(order,1);
				this.setState({list:current});
				//更新总金额
				var total = 0;
				for (var w=0;w<current.length ;w++ )
				{
					total += current[w][1]*current[w][2]/100;
				}
				total = total.toFixed(2);
				this.setState({total:total});
				//更新商品索引对应订单数量
				var data = this.state.data;
				
				for (var i=0;i<data.length ;i++ )
				{
					if (index == data[i].id)
					{
						
						data[i].order = 0;
						break;
					}
				}
				this.setState({data:data});
				
			}
			handleOrder(list){
				console.log(this.state.list);
				var current = this.state.list;
				//判断list中是否有相同商品的订单 有则更新订单数量即可
				var same = false;
				for (var c=0;c<current.length ;c++ )
				{	
					/*父组件list中的索引为商品的索引即id,渲染订单列表组件中
					的订单索引为自然顺序,需更改否则会影响产删除数据是更新商品订单的真是数量*/
					if (current[c].index == list.index)
					{
						same = true;
						current.splice(c,1,list);
					}
				}
				if (!same)
				{
					current.push(list);
				}
				this.setState({list:current});
				//合计总价
				var total = 0
				for (var w=0;w<current.length ;w++ )
				{
					total += current[w][1]*current[w][2]/100;
				}
				total = total.toFixed(2);
				this.setState({total:total});
				
				//更新data中对应商品的订单数
				var data = this.state.data;
				for (var i=0;i<data.length ;i++ )
				{
					if (list.index == data[i].id)
					{
						data[i].order = list[2];
						break;
					}
				}
				
				this.setState({data:data});
				
			}
			Change(val,index,variety){
				//更新商品中的值
				var data = this.state.data;
				switch(variety){
					case 'name':
						for (var nm=0;nm<data.length;nm++ )
						{
							if (index == data[nm].id)
							{
								data[nm].name = val;
								break;
							}
						}
						break;
					case 'price':
						for (var pr=0;pr<data.length;pr++ )
						{
							if (index == data[pr].id)
							{
								data[pr].price = val;
								break;
							}
						}
						break;
					case 'desc':
						for (var d=0;d<data.length;d++ )
						{
							if (index == data[d].id)
							{
								data[d].desc = val;
								break;
							}
						}
						break;
				}
				this.setState({data:data});
				
				//更新订单列表中的值
				var list = this.state.list;
				switch(variety){
					case 'name':
						for (var nm=0;nm<list.length;nm++ )
						{
							if (index == list[nm].index)
							{
								console.log('list');
								list[nm][0] = val;
								break;
							}
						}
						break;
					case 'price':
						for (var pr=0;pr<list.length;pr++ )
						{
							if (index == list[pr].index)
							{
								list[pr][1] = val;
								break;
							}
						}
						break;
				}
				this.setState({list:list});

				//更新总价
				var total = 0;
				for (var w=0;w<list.length ;w++ )
				{
					total += list[w][1]*list[w][2]/100;
				}
				total = total.toFixed(2);
				this.setState({total:total});
			}
			//是否售空状态更新 并清空data中对应商品的订单数
			select(status,index){
				var data = this.state.data;
				for (var s=0;s < data.length;s++ )
				{
					if(index == data[s].id){	
						data[s].saling = status;
						if(!status){
							data[s].order = 0;
						}
					}
				}
				this.setState({data:data});
				//更新总价
				var list = this.state.list;
				for (var l=0;l<list.length;l++){
					if (list[l].index == index){
						list.splice(l,1);
					}
				}
				var total = 0
				for (var w=0;w<list.length ;w++ )
				{
					total += list[w][1]*list[w][2]/100;
				}
				total = total.toFixed(2);
				this.setState({total:total});
			}
			Add(index){
				//更新订单列表的订单数
				var list = this.state.list;
				for (var l=0;l<list.length ;l++ )
				{
					if (index == list[l].index)
					{
						list[l][2]++;
					}
				}
				this.setState({list:list});
				var data = this.state.data;
				for (var d=0;d<data.length ;d++ )
				{
					if (index == data[d].id)
					{
						data[d].order++;
					}
				}
				this.setState({data:data});
				//更新总价
				var total = 0
				for (var w=0;w<list.length ;w++ )
				{
					total += list[w][1]*list[w][2]/100;
				}
				total = total.toFixed(2);
				this.setState({total:total});
				
			}
			Reduce(index){
				//更新订单列表的订单数
				var list = this.state.list;
				for (var l=0;l<list.length ;l++ )
				{
					if (index == list[l].index)
					{
						list[l][2]--;
					}
				}
				this.setState({list:list});
				var data = this.state.data;
				for (var d=0;d<data.length ;d++ )
				{
					if (index == data[d].id)
					{
						data[d].order--;
					}
				}
				this.setState({data:data});
				//更新总价
				var total = 0
				for (var w=0;w<list.length ;w++ )
				{
					total += list[w][1]*list[w][2]/100;
				}
				total = total.toFixed(2);
				this.setState({total:total});
			}
			render(){
					return <main>
								<Goods funcTrans={this.handleOrder} myData={this.state.data}></Goods>
								<Order funcDel={this.Del} funcAdd={this.Add} funcReduce={this.Reduce} myList={this.state.list} myTotal={this.state.total} myLength={this.state.list.length}></Order>
								<Saler funcChange={this.Change}  funcSelect={this.select} myData={this.state.data}></Saler>
							</main>
				}
        }
        /* Goods */ 
                class Goods extends React.Component{
					constructor(){
						super();
						this.FatherTrans = this.LisFatherTrans.bind(this);
					}
					LisFatherTrans(list){
						this.props.funcTrans(list);
					}
                    render(){
                        return <div id="goods">
                                    <img id='logo' src='logo.png' />
                                    <GoodsList myData={this.props.myData} funcTrans={this.FatherTrans}></GoodsList>
                                </div>
                    }
                }
                class GoodsList extends React.Component{
					constructor(){
						super();
						this.ListTrans = this.ListTrans.bind(this);
					}
					ListTrans(list){
						this.props.funcTrans(list);
					}
                    render(){ 
                        return <div>
                                {
                                    this.props.myData.map((item,index) => {
                                        return <GoodsItem funcTrans={this.ListTrans} key={item.id} myIndex={index} myData={item}></GoodsItem>;

                                    })
                                }
                            </div>
                    }
                }
                class GoodsItem extends React.Component{
                    constructor(){
                        super();
						
                        this.state = {
                            whetherHover:false,
							name:'',
							desc:'',
							price:0,
							order:0,
							index:0,
							saling:null
                        }
                        this.handleOver = this.handleOver.bind(this);
                        this.handleOut = this.handleOut.bind(this);
                        this.handleClick = this.handleClick.bind(this);
						
                    }
					//实时根据父组件state内容的更新而更新
					componentWillReceiveProps(nextProps) {
					  this.setState({
						name: nextProps.myData.name,
						id: nextProps.myData.id,
						desc: nextProps.myData.desc,
						price: nextProps.myData.price,
						order: nextProps.myData.order,
						saling:nextProps.myData.saling,
						
					  });
					 
					}
					componentDidMount(){
						var name = this.props.myData.name;
						var desc = this.props.myData.desc;
						var price = this.props.myData.price;
						var index = this.props.myData.id;
						var order = this.props.myData.order;
						var saling = this.props.myData.saling;
						this.setState({name:name});
						this.setState({desc:desc});
						this.setState({price:price});
						this.setState({index:index});
						this.setState({order:order});
						this.setState({saling:saling});
						
					}
                    handleClick(){
						if(!this.state.saling) return false;
						var orderNum = this.state.order;
						orderNum++;
						this.setState({order:orderNum});
						var temporary = [this.state.name,this.state.price,orderNum];
						temporary.index = this.props.myIndex;
						this.props.funcTrans(temporary);
                    }
                    handleOver(){
						if(!this.state.saling) return false;
                        this.setState({whetherHover:true});
                    }
                    handleOut(){
                        var now = this;
                        setTimeout(function(){
                            now.setState({whetherHover:false});
                        },500);
                    }
                    render(){
                        const addTolist = {
							p:{
								cursor:this.state.saling?'pointer':'inherit'
							},
                            first:{
                                background:'black',
                                height:this.state.whetherHover?'100%':'0px',
								display:this.state.saling?'inline-block':'none'
                            },
                            last:{
								borderColor:this.state.saling?'black':'#de4e70',
								color:this.state.saling?(this.state.whetherHover?'white':'black'):'#de4e70',
								transform:this.state.saling?'scale(1) rotate(0deg) translate(0px,0px)':'scale(1.6) rotate(-10deg) translate(20px,5px)',
								background:this.state.saling?'':'#fafafa'
							}
                        }
                        const {source,name,desc,price} = this.props.myData;
                        return <div className='goodsItem'>
                                    <div className='productImg'>
										<img src={source}/>
									</div>
                                    <div>
                                        <h3>{this.state.name}</h3>
                                        <p className='productContent'>{this.state.desc}</p>
                                        <p className='addToList' style={addTolist.p} onClick={this.handleClick} onMouseOver={this.handleOver} onMouseOut={this.handleOut}>
                                            <span style={addTolist.first}></span><span style={addTolist.last}>{this.state.saling?'ADD TO ORDER':'SOLD OUT!'}</span>
                                        </p>
                                        <p className='price'>${(this.state.price/100).toFixed(2)}</p>
                                    </div>
                                </div>
                    }
                }
        /* Order */
                class Order extends React.Component{
					constructor(){
						super();
						this.fatherDel = this.fatherDel.bind(this);
						this.myAdd = this.myAdd.bind(this);
						this.myReduce = this.myReduce.bind(this);
					}
					fatherDel(order,index){
						this.props.funcDel(order,index);
					}
					myAdd(index){
						this.props.funcAdd(index);
					}
					myReduce(index){
						this.props.funcReduce(index);
					}
                    render(){
                        return <div id="order">
                                    <h3>YOUR ORDER</h3>
									<OrderList funcDel={this.fatherDel} funcAdd={this.myAdd} funcReduce={this.myReduce} ownList={this.props.myList}></OrderList>
									<div style={{top:String((0.74*(this.props.myLength+1)+0.4).toFixed(2))+'rem'}}>
										<p id='total'>
											<span>Total:</span>
											<span>${this.props.myTotal}</span>
										</p>
									</div>
                                </div>
                    }
                }
				class OrderList extends React.Component{
					constructor(){
						super();
						this.listDel = this.listDel.bind(this);
						this.myAdd = this.myAdd.bind(this);
						this.myReduce = this.myReduce.bind(this);
					}
					listDel(order,index){
						console.log(order);
						this.props.funcDel(order,index);
					}
					myAdd(index){
						this.props.funcAdd(index);
					}
					myReduce(index){
						this.props.funcReduce(index);
					}
                    render(){
                        return <ul>
								{
									this.props.ownList.map((value,key)=>{
												//myIndex为商品索引 myKey为订单顺序索引
										return <OrderItems myInner={value} key={key} funcDel={this.listDel} funcAdd={this.myAdd} funcReduce={this.myReduce} myKey={key} myIndex={value.index}></OrderItems>;
										
									})
								}
							</ul>
                    }
                }
				class OrderItems extends React.Component{
					constructor(){
						super();
						this.state = {
							//组件是否挂载完毕
							ifMounted:false,
							//组件是否被点击删除
							//ifDeleting:false
						}
						this.handleDelete = this.handleDelete.bind(this);
						this.handleClick = this.handleClick.bind(this);
						this.handleAdd = this.handleAdd.bind(this);
						this.handleReduce = this.handleReduce.bind(this);
					}
					handleClick(){
						console.log(this.props.myKey);
					}
					handleDelete(){
						//this.props.funcDel(this.props.myKey,this.props.myIndex);
						var self = this;
						this.setState({ifDeleting:true});
						//在真正被删除前右滑,0.018s后直接消失,此时动画未完成
						setTimeout(function(){
							self.props.funcDel(self.props.myKey,self.props.myIndex);
							self.setState({ifDeleting:false});
						},180);
					}
					handleAdd(){
						this.props.funcAdd(this.props.myIndex);
					}
					handleReduce(){
						this.props.funcReduce(this.props.myIndex);
					}
					componentDidMount(){
						var now = this;
						//组件挂载完毕后在0.05s后右滑进入订单列表
                        setTimeout(function(){
                            now.setState({ifMounted:true});
                        },50);
						
					}
                    render(){
						
                        return <li className='orderItem' onClick={this.handleClick}
								//组件未挂载时在订单左侧未滑入
								//组件挂载完毕 并未点击删除时滑入订单区域保持不动
								//组件点击删除 在真正被删除前右滑
								//有个bug 组件被删除是下一个组件替代 此时被删除的组件所指代的索引的新组件的ifDeleting值仍未true
								//marginLeft:this.state.ifMounted?(this.state.ifDeleting?'100%':"0px"):"-100%"
						style={{marginLeft:this.state.ifMounted?"0px":"-100%",opacity:this.state.ifDeleting?'0':'1'}}>
									<span>{this.props.myInner[2]} lbs {this.props.myInner[0]}&nbsp;
										<b onClick={this.handleAdd}>+</b>
										<a href="javascript:;" onClick={this.handleDelete}>
											<b></b>
											<b>x</b>
										</a>
										<b onClick={this.handleReduce}>-</b>
									</span>
									<span>${String((this.props.myInner[1]*this.props.myInner[2]/100).toFixed(2))}</span>
								</li>
                    }
                }
        /* Saler */
                class Saler extends React.Component{
					constructor(){
						super();
						this.myChange = this.myChange.bind(this);
						this.mySelect = this.mySelect.bind(this);
					}
					myChange(val,index,variety){
						this.props.funcChange(val,index,variety);
					}
					mySelect(status,index){
						this.props.funcSelect(status,index);
					}
                    render(){
                        return <div id='saler'>
									<h3>INVENTORY</h3>
									<SalerList funcChange={this.myChange}  funcSelect={this.mySelect} myData={this.props.myData}></SalerList>
                                </div>
                    }
                }
				class SalerList extends React.Component{
					constructor(){
						super();
						this.myChange = this.myChange.bind(this);
						this.mySelect = this.mySelect.bind(this);
					}
					myChange(val,index,variety){
						this.props.funcChange(val,index,variety);
					}
					mySelect(status,index){
						this.props.funcSelect(status,index);
					}
                    render(){
                        return <div id='SalerList'>
									{
										this.props.myData.map((item,index) => {
											return <SaleItem funcChange={this.myChange} funcSelect={this.mySelect} key={item.id} myInner={item} myIndex={index}></SaleItem>
										})
									}
                                </div>
                    }
                }
				class SaleItem extends React.Component{
					constructor(){
						super();
						this.state = {
							name:'',
							price:0,
							desc:'',
							nameFocus:false,
							priceFocus:false,
							descFocus:false,
							selected:false,
							saling:null
						}
						this.nameChange = this.nameChange.bind(this);
						this.priceChange = this.priceChange.bind(this);
						this.descChange = this.descChange.bind(this);
						this.nameOnBlur = this.nameOnBlur.bind(this);
						this.priceOnBlur = this.priceOnBlur.bind(this);
						this.descOnBlur = this.descOnBlur.bind(this);
						this.nameFocus = this.nameFocus.bind(this);
						this.priceFocus = this.priceFocus.bind(this);
						this.descFocus = this.descFocus.bind(this);
						this.handleSelect = this.handleSelect.bind(this);
						this.selectFresh = this.selectFresh.bind(this);
						this.selectSold = this.selectSold.bind(this);
					}
					componentDidMount(){
						var name = this.props.myInner.name;
						var price = this.props.myInner.price;
						var desc = this.props.myInner.desc;
						var saling = this.props.myInner.saling;
						this.refs.myF.children[0].className = saling?'glyphicon glyphicon-ok':'';
						this.refs.myS.children[0].className = saling?'':'glyphicon glyphicon-ok';
						this.setState({name:name});
						this.setState({price:price});
						this.setState({desc:desc});
						this.setState({saling:saling});
						this.refs.myName.value = name;
						this.refs.myPrice.value = price;
						this.refs.myDesc.value = desc;
						
					}
					handleSelect(){
						this.setState({selected:true});
					}
					selectFresh(){
						//因为setState不会立即更新状态值 故赋值status并传递
						var status = true;
						this.setState({saling:true,selected:false});
						this.props.funcSelect(status,this.props.myIndex);
						this.refs.myF.children[0].className = 'glyphicon glyphicon-ok';
						this.refs.myS.children[0].className = '';
					}
					selectSold(){
						var status = false;
						this.setState({saling:false,selected:false});
						this.props.funcSelect(status,this.props.myIndex);
						this.refs.myS.children[0].className = 'glyphicon glyphicon-ok';
						this.refs.myF.children[0].className = '';
					}
					nameChange(){
						var name = this.refs.myName.value;
						this.setState({name:name});
						var type = 'name'; 
						this.props.funcChange(this.refs.myName.value,this.props.myIndex,type);
					}
					priceChange(){
						var price = this.refs.myPrice.value;
						this.setState({price:price});
						var type = 'price';
						this.props.funcChange(this.refs.myPrice.value,this.props.myIndex,type);
					}
					descChange(){
						var desc = this.refs.myDesc.value;
						this.setState({desc:desc});
						var type = 'desc';
						this.props.funcChange(this.refs.myDesc.value,this.props.myIndex,type);
						
					}
					nameFocus(){
						this.setState({nameFocus:true});
						
					}
					priceFocus(){
						this.setState({priceFocus:true});
						
					}
					descFocus(){
						this.setState({descFocus:true});
						
					}
					nameOnBlur(){
						this.setState({nameFocus:false});
					}
					priceOnBlur(){
						this.setState({priceFocus:false});
					}
					descOnBlur(){
						this.setState({descFocus:false});
					}
					render(){
						return <table className="table table-bordered">
							<tbody>
								<tr>
									<td>
										<input ref="myName" type="text" onBlur={this.nameOnBlur} onFocus={this.nameFocus} onChange={this.nameChange} style={{background:this.state.nameFocus?'#f4ecd8':'none'}}/>
									</td>
									<td>
										<input ref="myPrice" type="text" onBlur={this.priceOnBlur} onFocus={this.priceFocus} onChange={this.priceChange} style={{background:this.state.priceFocus?'#f4ecd8':'none'}}/>
									</td>
									<td>
										<p onClick={this.handleSelect}>{this.state.saling?'Fresh!':'Sold Out!'}</p>
										<ul ref='mySelect' style={{display:this.state.selected?'block':'none'}}>
											<li ref='myF' onClick={this.selectFresh}><span aria-hidden="true"></span>Fresh!</li>
											<li ref='myS' onClick={this.selectSold}><span aria-hidden="true"></span>Sold out!</li>
										</ul>
									</td>
								</tr>
								<tr>
									<td colSpan='3'>
										<textarea ref="myDesc" onBlur={this.descOnBlur} onFocus={this.descFocus} onKeyUp={this.descChange} style={{background:this.state.descFocus?'#f4ecd8':'none'}}>
										</textarea>
									</td>
								</tr>
								<tr>
									<td colSpan='3'>REMOVE FISH</td>
								</tr>
							</tbody>
						</table>
					}
				}
        ReactDOM.render(
            <Contain></Contain>,
            document.getElementById('box')
        )
		//https://reactforbeginners.com/images/using.mp4   
    </script>
	<!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery，所以必须放在前边) -->
    <script src="https://cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js"></script>
    <!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"></script>
 </body>
</html>
